package com.example.LightningController;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * User: master
 * Date: 6/5/13
 * Time: 11:16 PM
 * To change this template use File | Settings | File Templates.
 */
public class TempActivityWithSPPInterface extends Activity {
    private static final int REQUEST_ENABLE_BT = 2;
    private BluetoothAdapter bluetoothAdapter;
    private UUID applicationUUID = java.util.UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private static final String logTag = "BluetoothTest";

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            Log.d(logTag, "Could not get bluetooth adapter");
            return;
        }
        searchForDevices();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_ENABLE_BT) {
            if (requestCode == RESULT_OK) {
                Log.d("BluetoothTest", "bluetooth enabled");
                searchForDevices();
            } else {
                Log.d("BluetoothTest", "Could not enable bluetooth device");
            }
        }

    }

    public void lineReadFromBluetoothDevice(String line) {
        Log.d(logTag, "Mottok: " + line);
    }

    private void searchForDevices() {
        if (bluetoothAdapter.isEnabled()) {
            Set<BluetoothDevice> devicesAvailable = bluetoothAdapter.getBondedDevices();
            if (devicesAvailable.isEmpty()) {
                informUserNoDevicesPaired();
            } else {
                askUserToPickDeviceToUse(devicesAvailable);
            }
        } else {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }
    }

    private void askUserToPickDeviceToUse(Set<BluetoothDevice> devicesAvailable) {
        final ListView view = new ListView(this);
        view.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        ArrayAdapter<BluetoothDevice> adapter =
                new ArrayAdapter(this, R.layout.devicesavailabletextview, devicesAvailable.toArray(new BluetoothDevice[devicesAvailable.size()])) {

                    @Override
                    public View getView(int position, View convertView, ViewGroup parent) {
                        TextView view = (TextView) super.getView(position, convertView, parent);
                        BluetoothDevice bluetoothDevice = (BluetoothDevice) getItem(position);
                        view.setText(bluetoothDevice.getName() + " : " + bluetoothDevice.getAddress());
                        return view;
                    }
                };
        view.setAdapter(adapter);
        view.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
                pairToDevice((BluetoothDevice) view.getItemAtPosition(position));
            }
        });


        Dialog dialog = new Dialog(this);
        dialog.setContentView(view);
        dialog.setCancelable(true);
        dialog.show();

    }

    private void informUserNoDevicesPaired() {
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
        dialogBuilder.setMessage("Ingen \"Paired\" enheter");
        dialogBuilder.setPositiveButton("Søk", new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int arg1) {
                dialog.dismiss();
            }
        });
        dialogBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() {

            public void onCancel(DialogInterface dialog) {
                dialog.dismiss();
                finish();
            }
        });
        dialogBuilder.show();
    }

    private void showError(String message) {
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
        dialogBuilder.setMessage("Det oppstod en feil i programmet:\n\n" + message);
        dialogBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() {

            public void onCancel(DialogInterface dialog) {
                dialog.dismiss();
                finish();
            }
        });
        dialogBuilder.show();
    }

    private void pairToDevice(BluetoothDevice bluetoothDevice) {
        openSocket(bluetoothDevice);
    }

    private void openSocket(BluetoothDevice bluetoothDevice) {
        try {

            final ProgressDialog dialog = new ProgressDialog(this);
            final ConnectRunnable connector = new ConnectRunnable(bluetoothDevice, dialog);
            dialog.show(this, "Kobler til", "Koblier til " + bluetoothDevice.getName() + " : " + bluetoothDevice.getAddress(),
                    true, true,
                    new DialogInterface.OnCancelListener() {

                        public void onCancel(DialogInterface dialog) {
                            connector.cancel();
                        }
                    });

            new Thread(connector).start();

        } catch (IOException ex) {
            Log.d(logTag, "Could not open bluetooth socket", ex);
            showError("Kunne ikke åpne socket grunnet feil: " + ex.getMessage());
        } catch (IllegalAccessException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (InvocationTargetException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    private void closeSocket(BluetoothSocket openSocket) {
        try {
            openSocket.close();
        } catch (IOException ex) {
            Log.d(logTag, "Could not close exisiting socket", ex);
        }
    }

    private void startListeningForInput(BluetoothSocket socket) {
        new Thread(new InputReader(socket)).start();
    }

    private void dismissDialog(final Dialog dialog) {
        runOnUiThread(new Runnable() {

            public void run() {
                dialog.dismiss();
            }
        });
    }

    private class ConnectRunnable implements Runnable {

        private final ProgressDialog dialog;
        private final BluetoothSocket socket;

        public ConnectRunnable(BluetoothDevice device, ProgressDialog dialog) throws IOException, InvocationTargetException, IllegalAccessException {
            Method m = null;
            try {
                m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
            } catch (NoSuchMethodException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
            socket = (BluetoothSocket) m.invoke(device, 1);
            //socket = device.createRfcommSocketToServiceRecord(applicationUUID);
            this.dialog = dialog;
        }

        public void run() {
            try {
                bluetoothAdapter.cancelDiscovery();
                socket.connect();
            } catch (IOException connectException) {
                Log.d(logTag, "Could not connect to socket", connectException);
                closeSocket(socket);
                return;
            }
            startListeningForInput(socket);
            dismissDialog(dialog);
        }

        public void cancel() {
            try {
                socket.close();
            } catch (IOException e) {
                Log.d(logTag, "Canceled connection", e);
            }
        }
    }

    private class InputReader implements Runnable {

        private final BluetoothSocket socket;

        public InputReader(BluetoothSocket socket) {
            this.socket = socket;

        }

        @Override
        public void run() {

            //For writing
            OutputStream mmOutStream = null;
            try {
                mmOutStream = socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
            try {
                mmOutStream.write("2".getBytes());
                Log.d(logTag, "After sending 2");
            } catch (IOException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }

            //For reading
//            try {
//                final InputStream input = socket.getInputStream();
//                final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
//                String line;
//
//                while ((line = bufferedReader.readLine()) != null) {
//                    lineReadFromBluetoothDevice(line);
//                }
//            } catch (IOException ex) {
//                showError("Mistet forbindelsen: " + ex.getMessage());
//            }
        }

        public void cancel() {
            try {
                socket.close();
            } catch (IOException e) {
            }
        }
    }
}
